/* eslint-disable n/no-unsupported-features/es-syntax */
/* eslint-disable jsdoc/no-restricted-syntax */
/* eslint-disable camelcase */
/**
 * @template {Promise<any>} T
 * @param {T} fetch_promise
 * @param {AbortSignal} abortSignal
 * @returns {T}
 */
export function useAbortablePromise(fetch_promise, abortSignal) {
  // 这是一个可以被reject的promise
  const { promise: abort_promise, reject } = Promise.withResolvers();

  abortSignal.addEventListener("abort", () => {
    reject(new AbortError());
  });

  // 这里使用Promise.race，以最快 resolve 或 reject 的结果来传入后续绑定的回调

  const abortable_promise = /**
   * @type {T}
   */ (Promise.race([fetch_promise, abort_promise]));

  return abortable_promise;
}

// abort_controller.signal.onabort = () => {
//   console.log("abort promise");
// }
export class AbortError extends Error {
  constructor() {
    super("abort promise");
  }
}

const fetch_promise = Promise.resolve();
const abort_controller = new AbortController();
const abortable_promise = useAbortablePromise(
  fetch_promise,
  abort_controller.signal,
);
